package com.futvan.z.framework.util;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;

import org.apache.commons.codec.binary.Base64;

import com.futvan.z.framework.core.z;


/**
 * 区块链工具类
 * @author zj
 *
 */
public class BlockchainUtil {
	public static void main(String[] args) throws Exception {

//		Account k = 
		HashMap<String,String> k = CreateKey();
		
		System.out.println("钱包地址："+ k.get("public_key"));
		
		System.out.println("钱包密钥："+k.get("private_key"));
		

		//添加签名文本信息
		String text = "AJKFHKFSA98798779798797";
		
		//执行签名 
		String sign = sign(text,k.get("private_key"));
		System.out.println("签名后的数据："+sign);

		//验证签名
		boolean ok = verify(text,k.get("public_key"), sign);
		System.out.println("签名验证的结果：" + ok);

	}

	/**
	 * 	创建公钥与私钥对
	 * @return
	 * @throws Exception 
	 * @throws NoSuchAlgorithmException 
	 */
	public static HashMap<String,String> CreateKey() throws Exception{
		HashMap<String,String> key = null;
		try {
			//生成密钥对基础
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
			ECGenParameterSpec sEcSpec = new ECGenParameterSpec("secp256k1");
			keyPairGenerator.initialize(112);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();

			ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
			ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();

			key = new HashMap<String,String>();
			key.put("public_key", Base64.encodeBase64String(ecPublicKey.getEncoded()));
			key.put("private_key", Base64.encodeBase64String(ecPrivateKey.getEncoded()));
		} catch (NoSuchAlgorithmException e) {
			z.Error("创建公钥与私钥对出错",e);
		}
		return key;
	}

	/**
	 * 验证签名
	 * @param src 信息
	 * @param publicKeyEnc 公钥
	 * @param sign  签名串
	 * @return
	 */
	public static boolean verify(String src,String publicKey, String sign)
			throws NoSuchAlgorithmException, InvalidKeySpecException,
			InvalidKeyException, SignatureException {
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
		KeyFactory keyFactory = KeyFactory.getInstance("EC");
		PublicKey publick = keyFactory.generatePublic(x509EncodedKeySpec);
		
		Signature signature = Signature.getInstance("SHA1withECDSA");
		signature.initVerify(publick);
		signature.update(src.getBytes());
		return signature.verify(Base64.decodeBase64(sign)); //验证结果 
	}

	/**
	 * 执行签名
	 * @param src 信息
	 * @param privateKeyEnc 私钥
	 * @return 签名串
	 */
	public static String sign(String src,String privateKey)
			throws NoSuchAlgorithmException, InvalidKeySpecException,
			InvalidKeyException, SignatureException {
		KeyFactory keyFactory = KeyFactory.getInstance("EC");
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		
		//构建签名 
		Signature signature = Signature.getInstance("SHA1withECDSA");
		signature.initSign(priKey);
		signature.update(src.getBytes());
		String result = Base64.encodeBase64String(signature.sign()); //签名后的数据信息
		return result;
	}
}
